﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using FinanSoft.Entities;
using FinanSoft.BusinessLayer;
using FinanSoft.Utilities;
using System.Xml;
using System.Data.SqlClient;

namespace FinanSoft.PresentacionBancos
{
    public partial class frmPagos : Form
    {
        int QuienConsulta; //1 - Cliente, 2 - Proveedor
        private List<AuxiliarAccount> _auxAccountClientes = new List<AuxiliarAccount>();
        private List<AuxiliarAccount> _auxAccountProveedores = new List<AuxiliarAccount>();
        private List<OpenDocument> _openDocsList = new List<OpenDocument>();
        private List<int> _bankingIds;


       public frmPagos(int _QuienConsulta)
        {
            InitializeComponent();

            QuienConsulta = _QuienConsulta;

            //Limpia combobox
            cmbDocType.Items.Clear();
            //Asigna lista que corresponde
            if (QuienConsulta == Constants.IS_CLIENT_CODE)
            {
                lblQuieConsulta.Text = "Clientes:";
                agregarCliente(Constants.IS_CLIENT_CODE);
            }
            else
            {
                lblQuieConsulta.Text = "Proveedores:";
                agregarProveedor(Constants.IS_PROVIDER_CODE);
            }
            //Marca el primer valor
            cmbDocType.SelectedIndex = 0;
            fillBankingAccounts();
        }

        /// <summary>
        /// Método para llenar cuentas bancarias a las que se puede realizar cobro de facturas
        /// </summary>
       private void fillBankingAccounts()
       {
           _bankingIds = new List<int>();
           List<Account> bankingAccouts = CatalogManager.GetInstance().GetAccountingCatalog().GetSpecialAccounts(Constants.SpecialType.bankingAccount);
           foreach (Account account in bankingAccouts)
           {
               _bankingIds.Add(account.AccountID);
               cmbBankingAccount.Items.Add(account.Name);
           }
           if (bankingAccouts.Count > 0)
               cmbBankingAccount.SelectedIndex = 0;
       }

        // Funcion que me va metiendo en un combobox todas las cuentas auxiliares tipo cliente
        private void agregarCliente(int idTipoCtaAuxP)
        {
            AuxiliarAccount[] arregloCuentaAux = AuxiliaryAccountManager.GetInstance().GetAuxiliarAccountsListByType(idTipoCtaAuxP);

            for (int ele = 0; ele < arregloCuentaAux.Length; ele++)
            {
                cmbDocType.Items.Add(arregloCuentaAux[ele].OwnerName);
                _auxAccountClientes.Insert(ele, arregloCuentaAux[ele]);
            }

        }

        // Funcion que me va metiendo en un combobox todas las cuentas auxiliares tipo proveedor
        private void agregarProveedor(int idTipoCtaAuxP)
        {
            AuxiliarAccount[] arregloCuentaAux = AuxiliaryAccountManager.GetInstance().GetAuxiliarAccountsListByType(idTipoCtaAuxP);

            for (int ele = 0; ele < arregloCuentaAux.Length; ele++)
            {
                cmbDocType.Items.Add(arregloCuentaAux[ele].OwnerName);
                _auxAccountProveedores.Insert(ele, arregloCuentaAux[ele]);
            }

        }

        private void btnSalir_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void btnConsultar_Click(object sender, EventArgs e)
        {
            int idCtaAux = 0;

            if (QuienConsulta == 1) //Cliente
            {
                //Extrae el id de la cuenta auxiliar seleccionada
                idCtaAux = _auxAccountClientes[cmbDocType.SelectedIndex].AccountID;   
            }
            else
            {
                //Extrae el id de la cuenta auxiliar seleccionada
                idCtaAux = _auxAccountProveedores[cmbDocType.SelectedIndex].AccountID;   
            }
            // Realiza la consulta y se la asigna al grid
            limpiarGrid();
            agregarDocsAbiertos(idCtaAux);        
        }

        // Funcion que me va metiendo en un listbox todas las cuentas no especiales
        private void agregarDocsAbiertos(int idCtaAux)
        {
            // Verificamos que se haya seleccionado un client/proveedor
            if (cmbDocType.SelectedIndex == -1)
                MessageBox.Show(MessageConstants.NO_SELECTED_AUX_ACCOUNT, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Warning);
            else
            {
                OpenDocument[] arregloDocsAbiertos = OpenDocumentManager.GetInstance().GetOpenDoc(idCtaAux);
                for (int ele = 0; ele < arregloDocsAbiertos.Length; ele++)
                {
                    //Guarda los valores en una lista
                    arregloDocsAbiertos[ele].DocumentOwner = AuxiliaryAccountManager.GetInstance().GetAuxiliarAccount(idCtaAux);
                    _openDocsList.Insert(ele, arregloDocsAbiertos[ele]);
                    //Asigna los valores en el grid
                    gridOpenDocs.Rows.Add();
                    gridOpenDocs[1, ele].Value = _openDocsList[ele].tipoDocumento;
                    gridOpenDocs[2, ele].Value = _openDocsList[ele].codigoDocumento;
                    gridOpenDocs[3, ele].Value = _openDocsList[ele].fechaVencimiento;
                    gridOpenDocs[4, ele].Value = _openDocsList[ele].Currency.Symbol + " " + _openDocsList[ele].monto.ToString();
                }                
            }
        }

        // Funcion que me va metiendo en un listbox todas las cuentas no especiales
        private void limpiarGrid()
        {
            gridOpenDocs.Rows.Clear();
            gridOpenDocs.Refresh();
        }

        /// <summary>
        /// Realiza el pago de las facturas, se encarga de llamar a los asientos correspondientes y registrar las transferencias
        /// </summary>
        private void realizePayment()
        {
            if (cmbBankingAccount.SelectedIndex == Constants.INVALID_ID)
                MessageBox.Show(MessageConstants.NO_BANKING_ACCOUNT_SELECTED, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Warning);
            else
            {
                // Obtenemos todas las facturas que se quieren cancelar
                Account bankingAccount = CatalogManager.GetInstance().GetAccount(_bankingIds[cmbBankingAccount.SelectedIndex]);
                List<OpenDocument> bills = new List<OpenDocument>();
                for (int rowIndex = 0; rowIndex < gridOpenDocs.Rows.Count; rowIndex++)
                    // Solo sumamos aquellas facturas que escoge el usuario
                    if (Convert.ToBoolean(((DataGridViewCheckBoxCell)gridOpenDocs[0, rowIndex]).Value))
                        bills.Add(_openDocsList[rowIndex]);
                
                // Verifico que se haya seleccionado al menos una factura
                if (bills.Count == 0)
                    MessageBox.Show(MessageConstants.NO_CLIENT_PROVIDER_SELECTED, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                // Cancelo todas las facturas contra la cuenta bancaria
                if(!PaymentManager.GetInstance().RealizePayment(bills, bankingAccount, QuienConsulta))
                    MessageBox.Show(PaymentManager.GetInstance().ErrorMessage, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Error);
                else
                {
                    MessageBox.Show(MessageConstants.BILL_CANCELED, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                    limpiarGrid();
                    _openDocsList = new List<OpenDocument>();
                }
            }
        }

        private void btnCalcular_Click(object sender, EventArgs e)
        {
            // Calculamos el subtotal que habría que pagar de las cuentas que selecciona el usuario
            double subTotal = 0;
            // Esto es para identificar en que moneda se va a mostrar el monto
            bool manyCurrencies = false;
            int currentCurrencyId = Constants.INVALID_ID;
            if (_openDocsList.Count > 0)
                currentCurrencyId = _openDocsList[0].Currency.Id;
            for(int rowIndex = 0; rowIndex < gridOpenDocs.Rows.Count; rowIndex++)
            {
                // Solo sumamos aquellas facturas que escoge el usuario
                if (Convert.ToBoolean(((DataGridViewCheckBoxCell)gridOpenDocs[0, rowIndex]).Value))
                {
                    OpenDocument openDoc = _openDocsList[rowIndex];
                    if(openDoc.tipoDocumento == Constants.NC_ACCOUNTING_ENTRY)
                        subTotal -= openDoc.monto * openDoc.Currency.ToLocalCurrency;
                    else
                        subTotal += openDoc.monto * openDoc.Currency.ToLocalCurrency;
                    // Hay varias monedas combinadas asi que vamos a dejarlo con la moneda local
                    if (!manyCurrencies && openDoc.Currency.Id != currentCurrencyId)
                    {
                        manyCurrencies = true;
                        currentCurrencyId = MoneyManager.GetInstance().LocalCurrency.Id;
                    }
                }
            }
            // Caso especial de que no hay documentos disponibles
            if (currentCurrencyId == Constants.INVALID_ID)
                currentCurrencyId = MoneyManager.GetInstance().SystemCurrency.Id;
            // Establecemos el símbolo de la moneda del subtotal y establecemos las etiquetas
            string symbol = MoneyManager.GetInstance().GetCurrency(currentCurrencyId).Symbol;
            subTotalLabel.Text = symbol + " " + (subTotal / MoneyManager.GetInstance().GetCurrency(currentCurrencyId).ToLocalCurrency).ToString("0.00");
            discountLabel.Text = symbol + " 0.00";
            totalLabel.Text = subTotalLabel.Text;
        }

        private void btnAplicar_Click(object sender, EventArgs e)
        {
            realizePayment();
        }
    }
}
